package com.cyber.plus.model.entity;

import com.cyber.plus.registry.ModItems;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.EndermiteEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.entity.projectile.thrown.ThrownItemEntity;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

/**
 * 自定义实体
 * 集成一个可抛出的实体
 * 抄袭末影珍珠代码
 *
 * @version 1.0
 * @author: 贺坤
 * @createTime: 2023年07月09日 21:21
 */
public class CustomItemEntity extends ThrownItemEntity {


	public CustomItemEntity(World world, LivingEntity owner) {
		super((EntityType<? extends ThrownItemEntity>) EntityType.ENDER_PEARL, owner, world);
	}

	/**
	 * 获取默认项目
	 *
	 * @return
	 */
	@Override
	protected Item getDefaultItem() {
		return ModItems.CUSTOM_ITEM;
	}

	/**
	 * 命中实体的时候
	 * 对此实体应用损坏。子类之间的具体实现不同。
	 * LivingEntity有生命值，破坏实体会降低生命值。它还可以处理盾牌、掉落方块对头盔的额外伤害、设置攻击者、播放伤害声音等。
	 * 某些实体（如ItemEntity）也具有运行状况值，重写的方法会递减该值。还有几个实体，比如net.minecraft.entity.decoration.EndCrystalEntity，任何损坏都会丢弃实体（可能是爆炸）。
	 * 如果这被重写，它必须检查isInvulnerableTo的结果并提前返回。
	 * 返回值:
	 * 实体是否实际受损
	 * 请参阅:
	 * 对不可修复，LivingEntity.modifyAppliedDamage
	 * @param entityHitResult 命中结果
	 */
	@Override
	protected void onEntityHit(EntityHitResult entityHitResult) {
		super.onEntityHit(entityHitResult);
		System.out.println("************* 命中实体的时候");
//		命中结果
		entityHitResult
				// 获取实体
				.getEntity()
				// 破坏 疑似相当于 损坏当前道具
				.damage(DamageSource.thrownProjectile(this, this.getOwner()), 0.0f);
	}

	/**
	 * 碰撞的时候
	 * @param hitResult
	 */
	@Override
	protected void onCollision(HitResult hitResult) {
		System.out.println("************* 碰撞的时候");
		super.onCollision(hitResult);
		// 循环次数 好像有一些奇怪的设定, 无法开的特别大
		for (int i = 0; i < 32; ++i) {
			// 添加粒子效果
			this.world.addParticle(ParticleTypes.PORTAL,
			                       this.getX(),
			                       this.getY() + this.random.nextDouble() * 2.0,
			                       this.getZ(),
			                       this.random.nextGaussian(),
			                       0.0,
			                       this.random.nextGaussian());
		}
		// 当是在服务器执行 并且没有被删除的时候
		if (!this.world.isClient && !this.isRemoved()) {
			// 获取当前使用者
			Entity entity = this.getOwner();
			// 判断是否是服务器玩家
			if (entity instanceof ServerPlayerEntity) {
				// 服务器存储的 玩家
				ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) entity;
				// 与客户端的连接是打开的 并且世界一致, 没有睡觉
				if (serverPlayerEntity.networkHandler.getConnection().isOpen() && serverPlayerEntity.world == this.world && !serverPlayerEntity.isSleeping()) {
					// 末影螨 敌对生物
					EndermiteEntity endermiteEntity;
					// 判断条件
					if (this.random.nextFloat() < 0.05f && this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && (endermiteEntity = EntityType.ENDERMITE.create(
							this.world)) != null) {
						endermiteEntity.refreshPositionAndAngles(entity.getX(),
						                                         entity.getY(),
						                                         entity.getZ(),
						                                         entity.getYaw(),
						                                         entity.getPitch());
						this.world.spawnEntity(endermiteEntity);
					}
					// 判断是否拥有坐骑
					if (entity.hasVehicle()) {
						// 请求传送和卸载
						serverPlayerEntity.requestTeleportAndDismount(this.getX(), this.getY(), this.getZ());
					} else {
						// 请求传送
						entity.requestTeleport(this.getX(), this.getY(), this.getZ());
					}
					// 着陆
					entity.onLanding();
					// 设置受伤 跌倒类型 5点血
					entity.damage(DamageSource.FALL, 5.0f);
				}
			} else if (entity != null) {
				// 请求传送
				entity.requestTeleport(this.getX(), this.getY(), this.getZ());
				// 着陆
				entity.onLanding();
			}
			// 删除当前道具
			this.discard();
		}
	}

	/**
	 * 时刻
	 * API说明:
	 * 这可以被覆盖以添加额外的逻辑。super.tick（）；在这种情况下应该调用。
	 * 实现 说明:
	 * 默认情况下，这会将所有逻辑委托给baseTick。
	 * 请参阅:
	 * LivingEntity.tickMovement，net.minecraft.entity.mob.MobEntity.mobTick
	 */
	@Override
	public void tick() {
		System.out.println("************* tick");
		Entity entity = this.getOwner();
		if (entity instanceof PlayerEntity && !entity.isAlive()) {
			this.discard();
		} else {
			super.tick();
		}
	}

	/**
	 * 移动到世界
	 * @param destination
	 * @return
	@Override
	@Nullable
	public Entity moveToWorld(ServerWorld destination) {
		// 获取使用人
		Entity entity = this.getOwner();
		if (entity != null && entity.world.getRegistryKey() != destination.getRegistryKey()) {
			this.setOwner(null);
		}
		return super.moveToWorld(destination);
	}*/
}
